package com.example.noobpackage.logic.repository

import android.content.Context
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.liveData
import com.example.noobpackage.logic.dao.AppDatabase
import com.example.noobpackage.logic.model.ExpressData
import com.example.noobpackage.logic.network.OnlineExpressService
import com.example.noobpackage.logic.network.ServiceCreator
import com.example.noobpackage.tool.MyApplication
import kotlinx.coroutines.Dispatchers
import java.util.ArrayList

object ExpressRepository {
    private val applicationContext: Context = MyApplication.context

    private val expressDao = AppDatabase.getDatabase(applicationContext).expressDao()
    private val onlineExpressService = ServiceCreator.create<OnlineExpressService>()

    // 网络的快递数据
    private val onlineExpressList = MutableLiveData<List<ExpressData>>()

    // 本地的快递数据
    private val expressList: LiveData<List<ExpressData>> = expressDao.loadAllExpress()


    // 展示的全部快递数据
    private val allExpressList = MediatorLiveData<List<ExpressData>>()

    init {
        // 配置快递数据来源
        allExpressList.addSource(expressList) {
            val tempList = ArrayList<ExpressData>()
            for (item in it) {
                tempList.add(item)
            }
            onlineExpressList.value?.let {
                for (item in onlineExpressList.value!!) {
                    tempList.add(item)
                }
            }
            allExpressList.value = tempList
        }
        allExpressList.addSource(onlineExpressList) {
            val tempList = ArrayList<ExpressData>()
            expressList.value?.let {
                for (item in expressList.value!!) {
                    tempList.add(item)
                }
            }
            for (item in it) {
                tempList.add(item)
            }
            allExpressList.value = tempList
        }
    }

    fun getAllExpress(): LiveData<List<ExpressData>> {
        return allExpressList
    }

    suspend fun loadOnlineExpress(account: Long) {
        try {
            Log.d("AppNetwork", "load online express")
            val onlineExpressRes = onlineExpressService.loadProxyPackage(account)
            Log.d("AppNetwork", "load online express success")
            onlineExpressList.postValue(onlineExpressRes)
        } catch (e: Throwable) {
            Log.d("AppNetwork", "load online express fail")
            e.printStackTrace()
        }
    }

    suspend fun clearOnlineExpress() {
        try {
            val clearList = ArrayList<ExpressData>()
            Log.d("AppNetwork", "clear online express")
            onlineExpressList.setValue(clearList)
        } catch (e: Throwable) {
            Log.d("AppNetwork", "clear online express fail")
            e.printStackTrace()
        }
    }

    suspend fun addLocalExpress(express: ExpressData) {
        expressDao.insert(express)
    }

    suspend fun completeLocalExpress(express: ExpressData) {
        expressDao.completeExpress(express)
    }

    fun loadProxyExpressContact(marketId: String) = liveData(Dispatchers.IO) {
        try {
            emit(onlineExpressService.loadProxyPackageDetail(marketId))
        } catch (e: Throwable) {
            e.printStackTrace()
        }

    }

    fun publishExpress(express: ExpressData, account: Long, remarks: String, weight: String) =
        liveData(Dispatchers.IO) {
            try {
                Log.d("AppNetwork", "publish express $express")
                val res = onlineExpressService.publishPackage(
                    account,
                    remarks,
                    weight,
                    express.expressNumber,
                    express.expressTakingNumber,
                    express.expressType,
                    express.expressLocation
                )
                if (res.isSuccess) {
                    Log.d("AppNetwork", "publish express success")
                    // 从本地移除
                    expressDao.completeExpress(express)
                    emit(res.isSuccess)
                } else {
                    Log.d("AppNetwork", "publish express fail")
                    emit(res.isSuccess)
                }
            } catch (e: Throwable) {
                e.printStackTrace()
            }
        }

}